package util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import util.bean.ResultSetProcessor;

public class DatabaseForMySQLUtil {
    private final static Logger logger = LoggerFactory.getLogger(DatabaseForMySQLUtil.class);
    private static final ThreadLocal<Connection> pool = new ThreadLocal<Connection>();

    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() throws SQLException {
        Connection connection = pool.get();

        if (connection == null) {
            logger.info("创建一个新连接");

            connection = createConnection();
            pool.set(connection);
        }

        return connection;
    }

    public static Connection createConnection() throws SQLException {
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/shiro", "root", "1234");
    }

    public static Object query(String sql, ResultSetProcessor processor, Object... parameters) {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet rs = null;

        try {
            connection = getConnection();
            statement = connection.prepareStatement(sql);

            for (int i = 0; i < parameters.length; i++) {
                statement.setObject(i + 1, parameters[i]);
            }
            rs = statement.executeQuery();

            return processor.exec(rs);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            close(connection, statement, rs);
        }
    }

    public static int executeUpdate(String sql) {
        Connection connection = null;
        Statement statement = null;
        try {
            connection = getConnection();
            statement = connection.createStatement();

            return statement.executeUpdate(sql);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            close(connection, statement);
        }
    }

    public static long getLastInsertId() {
        Connection connection = null;
        Statement statement = null;
        ResultSet rs = null;
        try {
            String sql = "select last_insert_id() from dual";

            connection = getConnection();
            statement = connection.createStatement();
            rs = statement.executeQuery(sql);

            long lastId = -1;

            if (rs.next()) {
                lastId = rs.getLong(1);
            }
            return lastId;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            close(connection, statement, rs);
        }
    }

    public static void close(Connection connection, Statement statement) {
        close(connection, statement, null);
    }

    public static void close(Connection connection, Statement statement, ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (statement != null) {
                statement.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (connection != null && !connection.isClosed()) {
                pool.set(connection);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

}
